package com.itheima.aspect;

import com.itheima.service.OrderService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Date;

/*
       需求：在tb_equipment进行数据添加之前自动填充created和updated两个字段的值
       1.增强的方法是public void addEquipment(Equipment equipment)
                               equipmentMapper.insert(equipment);
       2.在方法里，通过反射获取要修改的字段对象，暴力反射，重新设置值
 */
@Component
@Aspect
public class MyAdvice {

    //切入点表达式找到切入点（增强的方法）
    @Pointcut("execution(* com.itheima.service..*.add*(..))")
    public void pt(){
    }

    //环绕通知
    @Around("pt()")
    public Object around(ProceedingJoinPoint pj) throws Throwable{
        //1.获取方法签名
        /*
                    what is method signature in java？
         Two of the components of a method declaration comprise the
         method signature—the method's name and the parameter types.
                方法声明的两个组件构成了方法签名 - 方法的名称和参数类型。
         */
        Signature signature = pj.getSignature();
        //signature是否是方法签名
        if(signature instanceof MethodSignature){
            MethodSignature ms = (MethodSignature) signature;
            //2.获取方法名称
            String methodName = ms.getName();
            //3.获取方法的参数类型
            Class parameterType = ms.getParameterTypes()[0];
            //4.获取created与updated域
            //反射，先获取需要修改的成员变量对象，暴力反射
            Field created = parameterType.getDeclaredField("created");
            Field updated = parameterType.getDeclaredField("updated");
            created.setAccessible(true);
            updated.setAccessible(true);
            //5.获取方法参数中的值
            Object args = pj.getArgs()[0];
            //6.获取参数中的created与updated的值
            Object createdVal = created.get(args);
            Object updatedVal = updated.get(args);
            //7.判断值是否为NULL,如果为NULL,则设置默认值
            if(createdVal==null){
                created.set(args,new Date());
            }
            if(updatedVal==null){
                updated.set(args,new Date());
            }
        }
        //8.执行原始方法
        return pj.proceed(pj.getArgs());
    }
}

